package com.zx.template.enums;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

@Component
public class EnumManager {

    /**
     *某个元素格式是：<枚举类名，<code，codeName>>
     */
    private static final Map<String,Map<Integer,String>>AllCodeMap = new HashMap<>();
    /**某个元素格式是：<枚举类名，<codeName，code>>
     * */
    private static final Map<String,Map<String,Integer>>AllCodeNameMap = new HashMap<>();

    public static Map<String,Map<Integer,String>> getAllCodeMap(){
        return AllCodeMap;
    }

    /**通过code值获取codeName
     * @param clazz 枚举类
     * @param code 枚举类的code值
     * @return
     */
    public static String getCodeName(Class<? extends BaseEnum> clazz,Integer code){
        if (Objects.isNull(clazz)){
            return "";
        }
        return getCodeName(clazz.getSimpleName(),code);
    }

    private static String getCodeName(String clazz, Integer code) {
        if (StrUtil.isBlank(clazz) || Objects.isNull(code)){
            return "";
        }
        final Map<Integer, String> codeMap = AllCodeMap.get(clazz);
        return codeMap.getOrDefault(code,"");
    }

    /**根据codeName 得到对应code
     * @param clazz 枚举类
     * @param codeName 枚举类中的codeName
     * @return
     */
    public static Integer getCodeByCodeName(Class<? extends BaseEnum> clazz,String codeName){
        if (Objects.isNull(clazz)){
            return 0;
        }
        return getCodeByCodeName(clazz.getSimpleName(),codeName);

    }
    public static Integer getCodeByCodeName(String clazz,String codeName){
        if (StrUtil.isBlank(clazz) ||StrUtil.isBlank(codeName) ){
            return 0;
        }
        final Map<String, Integer> codeNameMap = AllCodeNameMap.get(clazz);
        return codeNameMap.get(codeName);
    }
    @PostConstruct
    public void afterPropertiesSet(){
        final Reflections reflections = new Reflections(ClasspathHelper.forClass(BaseEnum.class), new SubTypesScanner());
        final Set<Class<? extends BaseEnum>> subTypesOf = reflections.getSubTypesOf(BaseEnum.class);
        if (CollUtil.isEmpty(subTypesOf)){
            return;
        }
        subTypesOf.forEach(base ->{
            final BaseEnum[] enumConstants = base.getEnumConstants();
            HashMap<Integer, String> codeMap = new HashMap<>();
            HashMap<String, Integer> codeNameMap = new HashMap<>();

            AllCodeMap.put(base.getSimpleName(),codeMap);
            AllCodeNameMap.put(base.getSimpleName(),codeNameMap);

            for (BaseEnum enumConstant : enumConstants) {
                codeMap.put(enumConstant.getCode(),enumConstant.getName());
                codeNameMap.put(enumConstant.getName(),enumConstant.getCode());
            }
        });
    }

}


